<?php
declare (strict_types = 1);

namespace app\api\controller\v1;

use app\api\base\ApiBase;
use app\api\service\serv\ArticleService;
use think\Exception;
use think\Request;

class IndexController extends ApiBase
{
    /***
     * @var array
     * @Author Vee7
     * @Date 2021/12/23
     * @Time 15:48
     * @Description 本Demo使用说明及规范
     * 1.常用功能使用资源路由，特殊的可以指定路由
     * 2.模型及数据库操作使用服务接口模式，控制器依赖注入调用
     * 3.控制器做数据接收，数据验证，服务调用，数据返回  其他的一律交给服务接口或其他设计模式
     * 4.控制器中不需要签名验证的写在 protected $noAuth = [];中
     * 5.目前注册仅需提供Email和password两个参数即可，可以设计为不允许注册，通过后台添加用户方式作为一种授权模式
     * 6.登陆时，请求除了携带登陆字段，还必须携带header头信息：did / version
     * 格式如下：
     * POST http://localhost:81/api/v1/login
     * @param email        547966838@qq.com
     * @param password     yhw1230
     * @header did(设备唯一标识)  5215656132356
     * @header version(版本号)   1.0
     * @return
     * {
            "code": 200,
            "message": "登陆成功",
            "time": 1640245123,
                "data": {
                "token": "MAOIU456461AKFALKFASASF",
                "uid": 2,
                "time": 1640245123
            }
        }
     *
     * 7.登陆成功后前端必须保存token和time两个值，访问需要权限的路由时携带
     *
     * 8.前端每次访问需要授权的路由格式如下：
     * POST http://localhost:81/api/v1/user
     * @header token MAOIU456461AKFALKFASASF
     * @header did 5215656132356
     * @header version 1.0
     * @header time 1640245123
     * @result 如果以上did，version，time参数的值能够与token解密后的值对应，则表示验证通过，可以访问，且解密后包含auid字段是用户id
     */

    /***
     * @var string[]
     * @Author Vee7
     * @Date 2021/12/24
     * @Time 10:10
     * @Description V0.11 版本接口更新说明：
     * 1.登录成功接口不再使用sign字段作为返回值给前端，改用Token值，是加密后的Cache的Key，签名sign始终保存在服务器cache中，避免签名被恶意解密，
     * 此后前端每次访问授权接口将sign改为token，服务端获取token，根据token从cache中取得签名并解密，然后对比解密后的数据与前端传递的其他值比较是否一致
     */

    //不进行登陆鉴权，否则必须先账户登录获取token，之后需要授权的页面都需要通过header传递token,did,version,time(登录时间戳)才可访问
    protected $noAuth = ['index'];

    //公共接口签名认证，表示前台必须传递sign,create_id,randomstr进行验证才能请求后端数据
    //用于解决前后端分离项目，且不同IP，不同服务器部署的情况下，接口防止被恶意调用。虽然该系统最大限度从代码层面进行了限制设计，但当然最有效最直接的办法依然是尽量不跨域，或从Hearder头层面限制请求源，又或者两者结合可以极大提高接口安全性。
    //但该设计的优点在于可更容易搭建类似某擎类的B2B平台，能够管理不同应用对系统数据的访问权限
    protected $needSign = ['index'];

    //测试接口签名认证方法，前台参考index/index/testApi方法及视图里的js加密方法，我（程序作者）已模拟成功，另外也可以自定义修改SignAuth验证中间件，做成Header头获取验证数据，当前是直接通过请求提交的验证数据
    public function index(Request $request,ArticleService $article)
    {
        try{
            $return = $article->getArticleData($request->param('data'));
            if(!empty($return['code'])) {
                return self::Error($return,$return['message'],$return['code']);
            }else{
                return self::Success($return);
            }
        }catch(Exception $e){
            return self::Error($return,$e->getMessage());
        }
    }
}
